CeresEngine 0.2.0
A game development framework
Loading...
Searching...
No Matches
Stream.hpp
Go to the documentation of this file.
1//
2// CeresEngine - A game development framework
3//
4// Created by Rogiel Sulzbach.
5// Copyright (c) 2018-2023 Rogiel Sulzbach. All rights reserved.
6//
7
8#pragma once
9
10#include "FilePath.hpp"
11
14
22
24
25#include <bit>
26#include <cstddef>
27#include <type_traits>
28
29namespace CeresEngine {
30
31 class DataStream;
32 class AsyncDataStream;
33
37
39#if CE_COMPILER_MSVC
40 inline constexpr std::size_t kStreamPolySize = sizeof(void*) * 16;
41#else
42 inline constexpr std::size_t kStreamPolySize = sizeof(void*) * 8;
43#endif
44
58 class IStream {
59 public:
60 IStream() = default;
61
62 IStream(const IStream&) noexcept = delete;
63 IStream& operator=(const IStream&) noexcept = delete;
64
67
69
70 public: // Seeking & Telling
77
80 [[nodiscard]] virtual bool isSeekable(Seek mode = Seek::Start) const noexcept { return false; }
81
88 virtual void seek(std::streamsize position, Seek mode = Seek::Start);
89
91 void skip(const size_t n) {
93 seek(std::streamsize(n), Seek::Current);
94 }
95
98 [[nodiscard]] virtual bool isTellable() const noexcept { return false; }
99
103 [[nodiscard]] virtual size_t tell();
104
108
112 [[nodiscard]] virtual size_t size();
113 };
114
117 public:
120
121 public:
122 using Poly::Poly;
123 };
124
126 class IInputStream : public virtual IStream {
127 public: // Reading
130 [[nodiscard]] virtual bool isReadable() const noexcept { return false; }
131
143 [[nodiscard]] virtual size_t read(void* data, size_t n);
144
149 template<typename T> [[nodiscard]] size_t read(const MemoryView<T>& memoryView) {
150 const ByteMemoryView byteMemoryView = memoryView.template as<Byte>();
151 return read(byteMemoryView.data(), byteMemoryView.size());
152 }
153
160 template<typename T> [[nodiscard]] size_t read(const StridedMemoryView<T>& memoryView) {
161 size_t totalBytesRead = 0;
162 for(const size_t index : indices<std::size_t>(memoryView)) {
163 const size_t bytesRead = read(&memoryView[index], sizeof(T));
164 totalBytesRead += bytesRead;
165
166 if(bytesRead != sizeof(T)) {
167 break;
168 }
169 }
170 return totalBytesRead;
171 }
172
174 [[nodiscard]] Optional<String> readString() {
175 CE_ASSERT(isReadable());
176
177 String string;
178 size_t length;
179 String::value_type buffer[1024];
180
181 while((length = read(buffer, sizeof(buffer))) != 0) {
182 string += StringView(buffer, length);
183 }
184
185 return string;
186 }
187
191 template<typename T>
192 requires std::is_trivially_copyable_v<T>
193 [[nodiscard]] Optional<T> read() {
194 T value;
195
196 const size_t bytes = read(&value, sizeof(T));
197 if(bytes != sizeof(T)) {
198 return nullopt;
199 }
200 return byteswap<std::endian::little>(value);
201 }
202
206 [[nodiscard]] virtual bool invalidate();
207 };
208
210 class InputStream final : public Poly<IInputStream, kStreamPolySize, false, IStream> {
211 public:
214
215 public:
216 using Poly::Poly;
217
218 InputStream(InputStream&&) noexcept = default;
219 InputStream& operator=(InputStream&&) noexcept = default;
220
223 explicit InputStream(const FilePath& path);
224
229 explicit InputStream(const ByteMemoryView& buffer, bool freeOnClose = false);
230 };
231
233 class IOutputStream : public virtual IStream {
234 public: // Writing
237 [[nodiscard]] virtual bool isWritable() const noexcept { return false; }
238
253 [[nodiscard]] virtual size_t write(const void* data, size_t n);
254
259 template<typename T> [[nodiscard]] size_t write(const MemoryView<const T>& memoryView) {
260 const MemoryView<const Byte> byteMemoryView = memoryView.template as<const Byte>();
261 return write(byteMemoryView.data(), byteMemoryView.size());
262 }
263
270 template<typename T> [[nodiscard]] size_t write(const StridedMemoryView<const T>& memoryView) {
271 size_t totalBytesWritten = 0;
272 for(const size_t index : indices<std::size_t>(memoryView)) {
273 const size_t bytesWritten = write(&memoryView[index], sizeof(T));
274 totalBytesWritten += bytesWritten;
275
276 if(bytesWritten != sizeof(T)) {
277 break;
278 }
279 }
280 return totalBytesWritten;
281 }
282
286 [[nodiscard]] size_t writeString(const StringView string) { return write(string.data(), string.length()); }
287
291 template<typename T>
292 requires std::is_trivially_copyable_v<T>
293 [[nodiscard]] bool write(T value) {
294#if 0
295 value = byteswap<std::endian::little>(value);
296#endif
297 return write(&value, sizeof(T)) == sizeof(T);
298 }
299
303 [[nodiscard]] virtual bool flush();
304 };
305
307 class OutputStream final : public Poly<IOutputStream, kStreamPolySize, false, IStream> {
308 public:
311
312 public:
313 using Poly::Poly;
314
317 explicit OutputStream(const FilePath& path);
318
323 explicit OutputStream(const ByteMemoryView& buffer, bool freeOnClose = false);
324 };
325
326 // ---------------------------------------------------------------------------------------------
327
329 public:
331 virtual ~IAsyncStream() = default;
332
333 public: // Seeking & Telling
336
339 [[nodiscard]] virtual bool isSeekable(Seek mode = Seek::Start) const noexcept { return false; }
340
347 virtual Async<> seek(std::streamsize position, Seek mode = Seek::Start);
348
350 Async<> skip(const size_t n) {
351 CE_ASSERT(isSeekable(Seek::Current));
352 return seek(std::streamsize(n), Seek::Current);
353 }
354
357 [[nodiscard]] virtual bool isTellable() const noexcept { return false; }
358
362 [[nodiscard]] virtual Async<size_t> tell();
363
366 [[nodiscard]] virtual bool isSizeKnown() const noexcept;
367
371 [[nodiscard]] virtual Async<size_t> size();
372
373 public:
377 [[nodiscard]] virtual Async<> wait() = 0;
378 };
379
381 class AsyncStream final : public Poly<IAsyncStream, kStreamPolySize, false> {
382 public:
383 using Poly::Poly;
384 };
385
386 class IAsyncInputStream : public virtual IAsyncStream {
387 public: // Reading
390 [[nodiscard]] virtual bool isReadable() const noexcept { return false; }
391
403 [[nodiscard]] virtual Async<size_t> read(void* data, size_t n);
404
408 [[nodiscard]] virtual Async<size_t> readExactly(void* data, size_t n);
409 };
410
412 class AsyncInputStream final : public Poly<IAsyncInputStream, kStreamPolySize, false> {
413 public:
414 using Poly::Poly;
415 };
416
417 class IAsyncOutputStream : public virtual IAsyncStream {
418 public: // Writing
421 [[nodiscard]] virtual bool isWritable() const noexcept { return false; }
422
437 [[nodiscard]] virtual Async<size_t> write(const void* data, size_t n);
438
442 [[nodiscard]] virtual Async<size_t> writeExactly(void* data, size_t n);
443 };
444
446 class AsyncOutputStream final : public Poly<IAsyncOutputStream, kStreamPolySize, false> {
447 public:
448 using Poly::Poly;
449 };
450
451 // ---------------------------------------------------------------------------------------------
452
453 class DataStream;
454
456 class IDataStream : public IInputStream, public IOutputStream {};
457
460 class DataStream final : public Poly<IDataStream, kStreamPolySize, false, IStream> {
461 public:
462 using Poly::Poly;
463
464 explicit DataStream(AsyncDataStream asyncDataStream);
465
468 explicit DataStream(const FilePath& path);
469
472 explicit DataStream(size_t size);
473
478 explicit DataStream(const ByteMemoryView& buffer, bool freeOnClose = false);
479
480 public:
487 [[nodiscard]] static size_t copy(InputStream input, OutputStream output, size_t buffer = 16 * 1024);
488 };
489
492
495 class AsyncDataStream final : public Poly<IAsyncDataStream, kStreamPolySize, false> {
496 public:
497 using Poly::Poly;
498
499 explicit AsyncDataStream(DataStream dataStream, ExecutionContext& executionContext);
500 };
501
502 // ---------------------------------------------------------------------------------------------
503
505 class AsyncDataStreamAdapter final : public IDataStream {
506 private:
508
509 public:
511
513
514 ~AsyncDataStreamAdapter() noexcept final;
515
516 public:
518 [[nodiscard]] bool isSeekable(const Seek mode = Seek::Start) const noexcept final {
519 CE_ASSERT(mDataStream != nullptr);
520 return mDataStream->isSeekable(mode);
521 }
522
524 void seek(std::streamsize position, Seek mode = Seek::Start) final;
525
527 [[nodiscard]] bool isTellable() const noexcept final {
528 CE_ASSERT(mDataStream != nullptr);
529 return mDataStream->isTellable();
530 }
531
533 [[nodiscard]] size_t tell() final;
534
536 [[nodiscard]] bool isSizeKnown() const noexcept final {
537 CE_ASSERT(mDataStream != nullptr);
538 return mDataStream->isSizeKnown();
539 }
540
542 [[nodiscard]] size_t size() final;
543
544 public: // Reading
546 [[nodiscard]] bool isReadable() const noexcept final {
547 CE_ASSERT(mDataStream != nullptr);
548 return mDataStream->isReadable();
549 }
550
552 [[nodiscard]] size_t read(void* data, size_t n) final;
553
554 public: // Writing
556 [[nodiscard]] bool isWritable() const noexcept final {
557 CE_ASSERT(mDataStream != nullptr);
558 return mDataStream->isWritable();
559 }
560
562 [[nodiscard]] size_t write(const void* data, size_t n) final;
563 };
564
567 private:
570
571 public:
572 explicit SyncDataStreamAdapter(DataStream dataStream, ExecutionContext& executionContext);
573
574 public:
576 [[nodiscard]] bool isSeekable(const Seek mode = Seek::Start) const noexcept final {
577 CE_ASSERT(mDataStream != nullptr);
578 return mDataStream->isSeekable(mode);
579 }
580
582 Async<> seek(std::streamsize position, Seek mode = Seek::Start) final;
583
585 [[nodiscard]] bool isTellable() const noexcept final {
586 CE_ASSERT(mDataStream != nullptr);
587 return mDataStream->isTellable();
588 }
589
591 [[nodiscard]] Async<size_t> tell() final;
592
594 [[nodiscard]] bool isSizeKnown() const noexcept final {
595 CE_ASSERT(mDataStream != nullptr);
596 return mDataStream->isSizeKnown();
597 }
598
600 [[nodiscard]] Async<size_t> size() final;
601
602 public: // Reading
604 [[nodiscard]] bool isReadable() const noexcept final {
605 CE_ASSERT(mDataStream != nullptr);
606 return mDataStream->isReadable();
607 }
608
610 [[nodiscard]] Async<size_t> read(void* data, size_t n) final;
611
612 public: // Writing
614 [[nodiscard]] bool isWritable() const noexcept final {
615 CE_ASSERT(mDataStream != nullptr);
616 return mDataStream->isWritable();
617 }
618
620 [[nodiscard]] Async<size_t> write(const void* data, size_t n) final;
621
622 public:
624 [[nodiscard]] Async<> wait() final;
625 };
626
628 class FileDataStream final : public IDataStream {
629 private:
632
634 FILE* stream = nullptr;
635
636 public:
639 explicit FileDataStream(const FilePath& path, bool writing = false);
640
644
649
652
653 public:
655 [[nodiscard]] const FilePath& getPath() const noexcept { return path; }
656
658 [[nodiscard]] FILE* getStream() const noexcept { return stream; }
659
660 public: // IDataStream interface
662 [[nodiscard]] bool isSeekable(Seek mode = Seek::Start) const noexcept final { return true; }
663
665 void seek(std::streamsize position, Seek mode = Seek::Start) final;
666
668 [[nodiscard]] bool isTellable() const noexcept final { return true; }
669
671 [[nodiscard]] size_t tell() final;
672
674 [[nodiscard]] bool isSizeKnown() const noexcept final { return true; }
675
677 [[nodiscard]] size_t size() final;
678
680 [[nodiscard]] bool isReadable() const noexcept final { return true; }
681
683 [[nodiscard]] size_t read(void* data, size_t n) final;
684
686 [[nodiscard]] bool isWritable() const noexcept final { return true; }
687
689 [[nodiscard]] size_t write(const void* data, size_t n) final;
690 };
691
693 class MemoryDataStream final : public IDataStream {
695 std::size_t mSize = 0;
696 std::size_t mPosition = 0;
697 bool mOwnsBuffer = true;
698
699 public:
702
705 explicit MemoryDataStream(size_t size);
706
712 MemoryDataStream(Byte* memory, size_t size, bool freeOnClose = false);
713
718 MemoryDataStream(const ByteMemoryView& buffer, bool freeOnClose = false);
719
721 explicit MemoryDataStream(DataStream& stream);
722
725
727
728 public:
730 [[nodiscard]] MemoryView<const Byte> getData() const { return MemoryView<const Byte>(mBuffer.slice(0, mSize)); }
731
733 [[nodiscard]] MemoryView<Byte> getData() { return mBuffer.slice(0, mSize); }
734
736 [[nodiscard]] bool isGrowable() const { return mOwnsBuffer; }
737
738 public: // IDataStream interface
740 [[nodiscard]] bool isSeekable(const Seek mode = Seek::Start) const noexcept final {
741 switch(mode) {
742 case Seek::Start:
743 case Seek::Current:
744 case Seek::End: return true;
745 default: return false;
746 }
747 }
748
750 void seek(std::streamsize position, Seek mode = Seek::Start) final;
751
753 [[nodiscard]] bool isTellable() const noexcept final { return true; }
754
756 [[nodiscard]] size_t tell() final { return mPosition; }
757
759 [[nodiscard]] bool isSizeKnown() const noexcept final { return true; }
760
762 [[nodiscard]] size_t size() final { return mSize; }
763
765 [[nodiscard]] bool isReadable() const noexcept final { return true; }
766
768 [[nodiscard]] size_t read(void* data, size_t n) final;
769 using IDataStream::read;
770
772 [[nodiscard]] bool isWritable() const noexcept final { return true; }
773
775 [[nodiscard]] size_t write(const void* data, size_t n) final;
776 using IDataStream::write;
777
778 private:
780 [[nodiscard]] bool growIfNeeded(std::size_t desiredSize);
781 };
782
784 class DataStreamBuffer final : public std::streambuf {
785 private:
788
791
793 char* mBuffer = nullptr;
794
795 public:
798 explicit DataStreamBuffer(DataStream dataStream, size_t bufferLength = 1024);
799
802
803 protected:
805 int underflow() override;
806 };
807
809 class InputStreamBuffer final : public std::streambuf {
810 private:
813
816
818 char* mBuffer = nullptr;
819
820 public:
823 explicit InputStreamBuffer(InputStream inputStream, size_t bufferLength = 1024);
824
827
828 protected:
830 int underflow() override;
831 };
832
833 // ---------------------------------------------------------------------------------------------
834
837 template<typename T> struct BinaryCodec;
838
842 template<typename T, typename... Args> T binaryRead(InputStream& stream, Args&&... args) {
843 return BinaryCodec<T>::read(*stream, std::forward<Args>(args)...);
844 }
845
847 template<typename T, typename S, typename... Args> T binaryRead(S& stream, Args&&... args) {
848 return BinaryCodec<T>::read(stream, std::forward<Args>(args)...);
849 }
850
852 template<typename T, typename... Args> Async<T> asyncBinaryRead(AsyncInputStream& stream, Args&&... args) {
853 return BinaryCodec<T>::asyncRead(*stream, std::forward<Args>(args)...);
854 }
855
857 template<typename T, typename S, typename... Args> Async<T> asyncBinaryRead(S& stream, Args&&... args) {
858 return BinaryCodec<T>::asyncRead(stream, std::forward<Args>(args)...);
859 }
860
864 template<typename T, typename... Args> void binaryWrite(OutputStream& stream, const T& value, Args&&... args) {
865 return BinaryCodec<T>::write(*stream, value, std::forward<Args>(args)...);
866 }
867
869 template<typename T, typename S, typename... Args> void binaryWrite(S& stream, const T& value, Args&&... args) {
870 return BinaryCodec<T>::write(stream, value, std::forward<Args>(args)...);
871 }
872
874 template<typename T, typename... Args> Async<> asyncBinaryWrite(AsyncOutputStream& stream, const T& value, Args&&... args) {
875 return BinaryCodec<T>::asyncWrite(*stream, value, std::forward<Args>(args)...);
876 }
877
879 template<typename T, typename S, typename... Args> Async<> asyncBinaryWrite(S& stream, const T& value, Args&&... args) {
880 return BinaryCodec<T>::asyncWrite(stream, value, std::forward<Args>(args)...);
881 }
882
884 template<typename T>
885 requires(std::is_trivially_copyable_v<T>) struct BinaryCodec<T> {
886 template<typename S> [[nodiscard]] static T read(S& stream) {
887 T value;
888 if(stream.read(&value, sizeof(T)) == sizeof(T)) {
889 return value;
890 }
891
892 throw StreamReadException("Could not read {0} bytes from the stream.", sizeof(T));
893 }
894
895 template<typename S> [[nodiscard]] static Async<T> asyncRead(S& stream) {
896 T value;
897 if(co_await stream.read(&value, sizeof(T)) == sizeof(T)) {
898 co_return value;
899 }
900
901 throw StreamReadException("Could not read {0} bytes from the stream.", sizeof(T));
902 }
903
904 template<typename S> static void write(S& stream, const T& value) {
905 if(stream.write(&value, sizeof(T)) == sizeof(T))
906 CE_LIKELY { return; }
907
908 throw StreamWriteException("Could not write {0} bytes to the stream.", sizeof(T));
909 }
910
911 template<typename S> static Async<> asyncWrite(S& stream, T value) {
912 if(co_await stream.write(&value, sizeof(T)) == sizeof(T))
913 CE_LIKELY { co_return; }
914
915 throw StreamWriteException("Could not write {0} bytes to the stream.", sizeof(T));
916 }
917 };
918
920 template<typename T, typename RawAllocator> struct BinaryCodec<BasicString<T, RawAllocator>> {
922
923 template<typename S, typename... Args> [[nodiscard]] static Type read(S& stream, Args&&... args) {
924 const UInt32 length = binaryRead<UInt32>(stream);
925
926 Type value(std::forward<Args>(args)...);
927 value.resize(length);
928
929 if(stream.read(&value, length * sizeof(T)) == length * sizeof(T)) {
930 return value;
931 }
932
933 throw StreamReadException("Could not read {0} bytes from the stream.", length * sizeof(T));
934 }
935
936 template<typename S, typename... Args> [[nodiscard]] static Async<Type> asyncRead(S& stream, Args&&... args) {
937 const UInt32 length = co_await binaryRead<UInt32>(stream);
938
939 Type value(std::forward<Args>(args)...);
940 value.resize(length);
941
942 if(co_await stream.read(&value, length * sizeof(T)) == length * sizeof(T)) {
943 co_return value;
944 }
945
946 throw StreamReadException("Could not read {0} bytes from the stream.", length * sizeof(T));
947 }
948
949 template<typename S> static void write(S& stream, const Type& value) {
950 binaryWrite<UInt32>(stream, UInt32(value.size()));
951 if(stream.write(value.data(), value.size() * sizeof(T)) == value.size() * sizeof(T)) {
952 return value.size() * sizeof(T);
953 }
954
955 throw StreamWriteException("Could not write {0} bytes to the stream.", value.size() * sizeof(T));
956 }
957
958 template<typename S> static Async<> asyncWrite(S& stream, const Type& value) {
959 co_await binaryWrite<UInt32>(stream, UInt32(value.size()));
960 if(stream.write(value.data(), value.size() * sizeof(T)) == value.size() * sizeof(T)) {
961 co_return value.size() * sizeof(T);
962 }
963
964 throw StreamWriteException("Could not write {0} bytes to the stream.", value.size() * sizeof(T));
965 }
966 };
967
970 template<typename T> struct BinaryCodec<BasicStringView<T>> {
972
973 static void write(IOutputStream& stream, const Type& value) {
974 binaryWrite<UInt32>(stream, UInt32(value.size()));
975 if(stream.write(value.data(), value.size() * sizeof(T)) == value.size() * sizeof(T)) {
976 return;
977 }
978
979 throw StreamWriteException("Could not write {0} bytes to the stream.", value.size() * sizeof(T));
980 }
981 };
982
984 class BinaryReader final {
985 private:
988
989 public:
990 explicit BinaryReader(InputStream inputStream) : mInputStream(std::move(inputStream)) {}
991 explicit BinaryReader(IInputStream& inputStream) : mInputStream(&inputStream) {}
992
993 public:
995 template<typename T, typename... Args> T read(Args&&... args) { return binaryRead<T>(mInputStream, std::forward<Args>(args)...); }
996
999 template<typename T, typename... Args> Optional<T> tryRead(Args&&... args) {
1000 try {
1001 return read<T>(std::forward<Args>(args)...);
1002 } catch(const StreamReadException&) {
1003 return nullopt;
1004 }
1005 }
1006
1008 [[nodiscard]] size_t read(void* data, const size_t n) {
1009 CE_ASSERT(mInputStream != nullptr);
1010 return mInputStream->read(data, n);
1011 }
1012
1013 public: // Seeking & Telling
1015
1017 [[nodiscard]] bool isSeekable(const Seek mode = Seek::Start) const noexcept {
1018 CE_ASSERT(mInputStream != nullptr);
1019 return mInputStream->isSeekable(mode);
1020 }
1021
1023 void seek(const std::streamsize position, const Seek mode = Seek::Start) {
1024 CE_ASSERT(mInputStream != nullptr);
1025 return mInputStream->seek(position, mode);
1026 }
1027
1029 void skip(const size_t n) {
1030 CE_ASSERT(mInputStream != nullptr);
1031 return mInputStream->skip(n);
1032 }
1033
1035 [[nodiscard]] bool isTellable() const noexcept {
1036 CE_ASSERT(mInputStream != nullptr);
1037 return mInputStream->isTellable();
1038 }
1039
1041 [[nodiscard]] size_t tell() {
1042 CE_ASSERT(mInputStream != nullptr);
1043 return mInputStream->tell();
1044 }
1045
1047 [[nodiscard]] bool isSizeKnown() const noexcept {
1048 CE_ASSERT(mInputStream != nullptr);
1049 return mInputStream->isSizeKnown();
1050 }
1051
1053 [[nodiscard]] size_t size() {
1054 CE_ASSERT(mInputStream != nullptr);
1055 return mInputStream->size();
1056 }
1057
1058 public:
1060 InputStream& getInputStream() { return mInputStream; }
1061
1063 const InputStream& getInputStream() const { return mInputStream; }
1064 };
1065
1067 class AsyncBinaryReader final {
1068 private:
1071
1072 public:
1073 explicit AsyncBinaryReader(AsyncInputStream inputStream) : mInputStream(std::move(inputStream)) {}
1074 explicit AsyncBinaryReader(IAsyncInputStream& inputStream) : mInputStream(&inputStream) {}
1075
1076 public:
1078 template<typename T, typename... Args> Async<T> read(Args&&... args) { return asyncBinaryRead<T>(mInputStream, std::forward<Args>(args)...); }
1079
1082 template<typename T, typename... Args> Async<Optional<T>> tryRead(Args&&... args) {
1083 try {
1084 co_return read<T>(std::forward<Args>(args)...);
1085 } catch(const StreamReadException&) {
1086 co_return nullopt;
1087 }
1088 }
1089
1091 [[nodiscard]] Async<size_t> read(void* data, const size_t n) {
1092 CE_ASSERT(mInputStream != nullptr);
1093 return mInputStream->read(data, n);
1094 }
1095
1096 public: // Seeking & Telling
1098
1100 [[nodiscard]] bool isSeekable(const Seek mode = Seek::Start) const noexcept {
1101 CE_ASSERT(mInputStream != nullptr);
1102 return mInputStream->isSeekable(mode);
1103 }
1104
1106 Async<> seek(const std::streamsize position, const Seek mode = Seek::Start) {
1107 CE_ASSERT(mInputStream != nullptr);
1108 return mInputStream->seek(position, mode);
1109 }
1110
1112 Async<> skip(const size_t n) {
1113 CE_ASSERT(mInputStream != nullptr);
1114 return mInputStream->skip(n);
1115 }
1116
1118 [[nodiscard]] bool isTellable() const noexcept {
1119 CE_ASSERT(mInputStream != nullptr);
1120 return mInputStream->isTellable();
1121 }
1122
1124 [[nodiscard]] Async<size_t> tell() {
1125 CE_ASSERT(mInputStream != nullptr);
1126 return mInputStream->tell();
1127 }
1128
1130 [[nodiscard]] bool isSizeKnown() const noexcept {
1131 CE_ASSERT(mInputStream != nullptr);
1132 return mInputStream->isSizeKnown();
1133 }
1134
1136 [[nodiscard]] Async<size_t> size() {
1137 CE_ASSERT(mInputStream != nullptr);
1138 return mInputStream->size();
1139 }
1140
1141 public:
1143 AsyncInputStream& getInputStream() { return mInputStream; }
1144
1146 const AsyncInputStream& getInputStream() const { return mInputStream; }
1147 };
1148
1150 class BinaryWriter final {
1151 private:
1154
1155 public:
1156 explicit BinaryWriter(OutputStream outputStream) : mOutputStream(std::move(outputStream)) {}
1157 explicit BinaryWriter(IOutputStream& outputStream) : mOutputStream(&outputStream) {}
1158
1159 public:
1161 template<typename T, typename... Args> void write(const T& value, Args&&... args) {
1162 return binaryWrite<T>(mOutputStream, value, std::forward<Args>(args)...);
1163 }
1164
1167 template<typename T, typename... Args> bool tryWrite(const T& value, Args&&... args) {
1168 try {
1169 write<T>(value, std::forward<Args>(args)...);
1170 return true;
1171 } catch(const StreamWriteException&) {
1172 return false;
1173 }
1174 }
1175
1177 [[nodiscard]] size_t write(const void* data, const size_t n) {
1178 CE_ASSERT(mOutputStream != nullptr);
1179 return mOutputStream->write(data, n);
1180 }
1181
1182 public: // Seeking & Telling
1184
1186 [[nodiscard]] bool isSeekable(const Seek mode = Seek::Start) const noexcept {
1187 CE_ASSERT(mOutputStream != nullptr);
1188 return mOutputStream->isSeekable(mode);
1189 }
1190
1192 void seek(const std::streamsize position, const Seek mode = Seek::Start) {
1193 CE_ASSERT(mOutputStream != nullptr);
1194 return mOutputStream->seek(position, mode);
1195 }
1196
1198 void skip(const size_t n) {
1199 CE_ASSERT(mOutputStream != nullptr);
1200 return mOutputStream->skip(n);
1201 }
1202
1204 [[nodiscard]] bool isTellable() const noexcept {
1205 CE_ASSERT(mOutputStream != nullptr);
1206 return mOutputStream->isTellable();
1207 }
1208
1210 [[nodiscard]] size_t tell() {
1211 CE_ASSERT(mOutputStream != nullptr);
1212 return mOutputStream->tell();
1213 }
1214
1216 [[nodiscard]] bool isSizeKnown() const noexcept {
1217 CE_ASSERT(mOutputStream != nullptr);
1218 return mOutputStream->isSizeKnown();
1219 }
1220
1222 [[nodiscard]] size_t size() {
1223 CE_ASSERT(mOutputStream != nullptr);
1224 return mOutputStream->size();
1225 }
1226
1227 public:
1229 [[nodiscard]] OutputStream& getOutputStream() { return mOutputStream; }
1230
1232 [[nodiscard]] const OutputStream& getOutputStream() const { return mOutputStream; }
1233 };
1234
1236 class AsyncBinaryWriter final {
1237 private:
1240
1241 public:
1242 explicit AsyncBinaryWriter(AsyncOutputStream outputStream) : mOutputStream(std::move(outputStream)) {}
1243 explicit AsyncBinaryWriter(IAsyncOutputStream& outputStream) : mOutputStream(&outputStream) {}
1244
1245 public:
1247 template<typename T, typename... Args> Async<> write(const T& value, Args&&... args) {
1248 return asyncBinaryWrite<T>(mOutputStream, value, std::forward<Args>(args)...);
1249 }
1250
1253 template<typename T, typename... Args> Async<bool> tryWrite(const T& value, Args&&... args) {
1254 try {
1255 co_await write<T>(value, std::forward<Args>(args)...);
1256 co_return true;
1257 } catch(const StreamWriteException&) {
1258 co_return false;
1259 }
1260 }
1261
1263 [[nodiscard]] Async<size_t> write(const void* data, const size_t n) {
1264 CE_ASSERT(mOutputStream != nullptr);
1265 return mOutputStream->write(data, n);
1266 }
1267
1268 public: // Seeking & Telling
1270
1272 [[nodiscard]] bool isSeekable(const Seek mode = Seek::Start) const noexcept {
1273 CE_ASSERT(mOutputStream != nullptr);
1274 return mOutputStream->isSeekable(mode);
1275 }
1276
1278 Async<> seek(const std::streamsize position, const Seek mode = Seek::Start) {
1279 CE_ASSERT(mOutputStream != nullptr);
1280 return mOutputStream->seek(position, mode);
1281 }
1282
1284 Async<> skip(const size_t n) {
1285 CE_ASSERT(mOutputStream != nullptr);
1286 return mOutputStream->skip(n);
1287 }
1288
1290 [[nodiscard]] bool isTellable() const noexcept {
1291 CE_ASSERT(mOutputStream != nullptr);
1292 return mOutputStream->isTellable();
1293 }
1294
1296 [[nodiscard]] Async<size_t> tell() {
1297 CE_ASSERT(mOutputStream != nullptr);
1298 return mOutputStream->tell();
1299 }
1300
1302 [[nodiscard]] bool isSizeKnown() const noexcept {
1303 CE_ASSERT(mOutputStream != nullptr);
1304 return mOutputStream->isSizeKnown();
1305 }
1306
1308 [[nodiscard]] Async<size_t> size() {
1309 CE_ASSERT(mOutputStream != nullptr);
1310 return mOutputStream->size();
1311 }
1312
1313 public:
1315 [[nodiscard]] AsyncOutputStream& getOutputStream() { return mOutputStream; }
1316
1318 [[nodiscard]] const AsyncOutputStream& getOutputStream() const { return mOutputStream; }
1319 };
1320
1321} // namespace CeresEngine
#define CE_EXCEPTION_DECL2(Name, Parent)
Definition Exception.hpp:100
#define CE_LIKELY
Definition Macros.hpp:396
#define CE_ASSERT(...)
Definition Macros.hpp:323
A reader that parses data from an underlying input stream as binary data.
Definition Stream.hpp:1067
bool isSizeKnown() const noexcept
Checks if the stream knows the size of the data.
Definition Stream.hpp:1130
Async seek(const std::streamsize position, const Seek mode=Seek::Start)
Changes the position of the data stream.
Definition Stream.hpp:1106
Async< size_t > tell()
Gets the absolute stream position, in bytes.
Definition Stream.hpp:1124
AsyncBinaryReader(AsyncInputStream inputStream)
Definition Stream.hpp:1073
Async skip(const size_t n)
Skips n bytes from the data stream.
Definition Stream.hpp:1112
AsyncInputStream mInputStream
The input stream to which data will be read from.
Definition Stream.hpp:1070
const AsyncInputStream & getInputStream() const
The input stream to which data will be read from.
Definition Stream.hpp:1146
Async< size_t > size()
Gets the number of bytes available on the stream.
Definition Stream.hpp:1136
Async< Optional< T > > tryRead(Args &&... args)
Tries to read a data type from the stream.
Definition Stream.hpp:1082
Async< size_t > read(void *data, const size_t n)
Reads data from the data stream to a buffer of raw memory data with length n.
Definition Stream.hpp:1091
Async< T > read(Args &&... args)
Reads a binary representation of T from the stream.
Definition Stream.hpp:1078
bool isTellable() const noexcept
Checks if the stream knows it's current absolute position.
Definition Stream.hpp:1118
bool isSeekable(const Seek mode=Seek::Start) const noexcept
Checks if the stream is seekable.
Definition Stream.hpp:1100
AsyncBinaryReader(IAsyncInputStream &inputStream)
Definition Stream.hpp:1074
AsyncInputStream & getInputStream()
The input stream to which data will be read from.
Definition Stream.hpp:1143
A writer that writes data to an underlying output stream as binary data.
Definition Stream.hpp:1236
Async< size_t > size()
Gets the number of bytes available on the stream.
Definition Stream.hpp:1308
bool isSizeKnown() const noexcept
Checks if the stream knows the size of the data.
Definition Stream.hpp:1302
bool isSeekable(const Seek mode=Seek::Start) const noexcept
Checks if the stream is seekable.
Definition Stream.hpp:1272
Async write(const T &value, Args &&... args)
Writes a binary representation of T to the stream.
Definition Stream.hpp:1247
AsyncBinaryWriter(AsyncOutputStream outputStream)
Definition Stream.hpp:1242
Async< size_t > write(const void *data, const size_t n)
Writes data to the data stream from a buffer of raw memory data with length n.
Definition Stream.hpp:1263
Async< bool > tryWrite(const T &value, Args &&... args)
Tries to write a data type to the stream.
Definition Stream.hpp:1253
AsyncOutputStream & getOutputStream()
The output stream to which data will be written to.
Definition Stream.hpp:1315
Async seek(const std::streamsize position, const Seek mode=Seek::Start)
Changes the position of the data stream.
Definition Stream.hpp:1278
const AsyncOutputStream & getOutputStream() const
The output stream to which data will be written to.
Definition Stream.hpp:1318
bool isTellable() const noexcept
Checks if the stream knows it's current absolute position.
Definition Stream.hpp:1290
Async skip(const size_t n)
Skips n bytes from the data stream.
Definition Stream.hpp:1284
AsyncBinaryWriter(IAsyncOutputStream &outputStream)
Definition Stream.hpp:1243
Async< size_t > tell()
Gets the absolute stream position, in bytes.
Definition Stream.hpp:1296
AsyncOutputStream mOutputStream
The output stream to which data will be written to.
Definition Stream.hpp:1239
An adapter stream that turns an AsyncDataStream into a DataStream.
Definition Stream.hpp:505
size_t size() final
Gets the number of bytes available on the stream.
AsyncDataStream mDataStream
Definition Stream.hpp:507
bool isTellable() const noexcept final
Checks if the stream knows it's current absolute position.
Definition Stream.hpp:527
AsyncDataStreamAdapter(AsyncDataStreamAdapter &&) noexcept=default
AsyncDataStreamAdapter(AsyncDataStream dataStream)
size_t write(const void *data, size_t n) final
Writes data to the data stream from a buffer of raw memory data with length n.
size_t read(void *data, size_t n) final
Reads data from the data stream to a buffer of raw memory data with length n.
void seek(std::streamsize position, Seek mode=Seek::Start) final
Changes the position of the data stream.
size_t tell() final
Gets the absolute stream position, in bytes.
bool isWritable() const noexcept final
Checks if the stream is writable.
Definition Stream.hpp:556
General purpose class used for encapsulating the reading and writing of data from and to various asyn...
Definition Stream.hpp:495
AsyncDataStream(DataStream dataStream, ExecutionContext &executionContext)
Definition Stream.hpp:412
Definition Stream.hpp:446
Definition Stream.hpp:381
A reader that parses data from an underlying input stream as binary data.
Definition Stream.hpp:984
BinaryReader(IInputStream &inputStream)
Definition Stream.hpp:991
T read(Args &&... args)
Reads a binary representation of T from the stream.
Definition Stream.hpp:995
size_t tell()
Gets the absolute stream position, in bytes.
Definition Stream.hpp:1041
InputStream & getInputStream()
The input stream to which data will be read from.
Definition Stream.hpp:1060
void seek(const std::streamsize position, const Seek mode=Seek::Start)
Changes the position of the data stream.
Definition Stream.hpp:1023
void skip(const size_t n)
Skips n bytes from the data stream.
Definition Stream.hpp:1029
const InputStream & getInputStream() const
The input stream to which data will be read from.
Definition Stream.hpp:1063
size_t read(void *data, const size_t n)
Reads data from the data stream to a buffer of raw memory data with length n.
Definition Stream.hpp:1008
size_t size()
Gets the number of bytes available on the stream.
Definition Stream.hpp:1053
bool isTellable() const noexcept
Checks if the stream knows it's current absolute position.
Definition Stream.hpp:1035
BinaryReader(InputStream inputStream)
Definition Stream.hpp:990
InputStream mInputStream
The input stream to which data will be read from.
Definition Stream.hpp:987
bool isSizeKnown() const noexcept
Checks if the stream knows the size of the data.
Definition Stream.hpp:1047
bool isSeekable(const Seek mode=Seek::Start) const noexcept
Checks if the stream is seekable.
Definition Stream.hpp:1017
Optional< T > tryRead(Args &&... args)
Tries to read a data type from the stream.
Definition Stream.hpp:999
A writer that writes data to an underlying output stream as binary data.
Definition Stream.hpp:1150
void seek(const std::streamsize position, const Seek mode=Seek::Start)
Changes the position of the data stream.
Definition Stream.hpp:1192
bool tryWrite(const T &value, Args &&... args)
Tries to write a data type to the stream.
Definition Stream.hpp:1167
bool isSizeKnown() const noexcept
Checks if the stream knows the size of the data.
Definition Stream.hpp:1216
OutputStream & getOutputStream()
The output stream to which data will be written to.
Definition Stream.hpp:1229
size_t write(const void *data, const size_t n)
Writes data to the data stream from a buffer of raw memory data with length n.
Definition Stream.hpp:1177
OutputStream mOutputStream
The output stream to which data will be written to.
Definition Stream.hpp:1153
BinaryWriter(OutputStream outputStream)
Definition Stream.hpp:1156
void skip(const size_t n)
Skips n bytes from the data stream.
Definition Stream.hpp:1198
size_t tell()
Gets the absolute stream position, in bytes.
Definition Stream.hpp:1210
bool isSeekable(const Seek mode=Seek::Start) const noexcept
Checks if the stream is seekable.
Definition Stream.hpp:1186
void write(const T &value, Args &&... args)
Writes a binary representation of T to the stream.
Definition Stream.hpp:1161
BinaryWriter(IOutputStream &outputStream)
Definition Stream.hpp:1157
bool isTellable() const noexcept
Checks if the stream knows it's current absolute position.
Definition Stream.hpp:1204
const OutputStream & getOutputStream() const
The output stream to which data will be written to.
Definition Stream.hpp:1232
size_t size()
Gets the number of bytes available on the stream.
Definition Stream.hpp:1222
A streambuf implementation for a DataStream.
Definition Stream.hpp:784
DataStreamBuffer(DataStream dataStream, size_t bufferLength=1024)
Creates a new StreamBuffer.
DataStream mDataStream
The resource stream.
Definition Stream.hpp:787
~DataStreamBuffer() final
Releases the ResourceStream.
size_t mBufferLength
The length of the allocated buffer.
Definition Stream.hpp:790
General purpose class used for encapsulating the reading and writing of data from and to various sour...
Definition Stream.hpp:460
DataStream(const ByteMemoryView &buffer, bool freeOnClose=false)
Wrap an existing memory chunk in a stream.
DataStream(AsyncDataStream asyncDataStream)
DataStream(size_t size)
Allocates a new chunk of memory and wraps it in a stream.
static size_t copy(InputStream input, OutputStream output, size_t buffer=16 *1024)
Copies data by reading data from the input stream and writes it to output stream.
DataStream(const FilePath &path)
Creates a new file stream by opening the file at the given path.
A context for function object execution.
Definition ExecutionContext.hpp:90
A data stream that reads or writes data into a file.
Definition Stream.hpp:628
bool isTellable() const noexcept final
Checks if the stream knows it's current absolute position.
Definition Stream.hpp:668
size_t read(void *data, size_t n) final
Reads data from the data stream to a buffer of raw memory data with length n.
FileDataStream(const FileDataStream &other)
Creates a new file data stream by opening the same file as other.
size_t size() final
Gets the number of bytes available on the stream.
FilePath path
The path to the file open in the stream.
Definition Stream.hpp:631
~FileDataStream() final
Destroys the data stream and closes the file.
size_t tell() final
Gets the absolute stream position, in bytes.
FILE * getStream() const noexcept
The open stream descriptor.
Definition Stream.hpp:658
size_t write(const void *data, size_t n) final
Writes data to the data stream from a buffer of raw memory data with length n.
void seek(std::streamsize position, Seek mode=Seek::Start) final
Changes the position of the data stream.
FileDataStream(FileDataStream &&other) noexcept
Creates a new file data stream by moving the already open stream other.
FileDataStream(const FilePath &path, bool writing=false)
Creates a new file stream by opening the file at the given path.
bool isWritable() const noexcept final
Checks if the stream is writable.
Definition Stream.hpp:686
bool isSeekable(Seek mode=Seek::Start) const noexcept final
Checks if the stream is seekable.
Definition Stream.hpp:662
Path to file or directory.
Definition FilePath.hpp:37
An interface that all asynchronous data streams must implement.
Definition Stream.hpp:491
Definition Stream.hpp:386
virtual Async< size_t > read(void *data, size_t n)
Reads data from the data stream to a buffer of raw memory data with length n.
virtual Async< size_t > readExactly(void *data, size_t n)
Similar to read(void*, size_t), but ensures that the entire data buffer is filled with exactly n byte...
virtual bool isReadable() const noexcept
Checks if the stream is readable.
Definition Stream.hpp:390
Definition Stream.hpp:417
virtual Async< size_t > write(const void *data, size_t n)
Writes data tp the data stream from a buffer of raw memory data with length n.
virtual Async< size_t > writeExactly(void *data, size_t n)
Similar to write(const void*, size_t), but ensures that the entire data buffer is written with exactl...
virtual bool isWritable() const noexcept
Checks if the stream is writable.
Definition Stream.hpp:421
Definition Stream.hpp:328
virtual Async seek(std::streamsize position, Seek mode=Seek::Start)
Changes the position of the data stream.
virtual Async< size_t > tell()
Gets the number of bytes available on the stream.
virtual ~IAsyncStream()=default
Default virtual destructor.
virtual bool isSizeKnown() const noexcept
Checks if the stream knows the size of the data.
Async skip(const size_t n)
Skips n bytes from the data stream.
Definition Stream.hpp:350
virtual bool isSeekable(Seek mode=Seek::Start) const noexcept
Checks if the stream is seekable.
Definition Stream.hpp:339
virtual bool isTellable() const noexcept
Checks if the stream knows the size of the data.
Definition Stream.hpp:357
An interface that all data streams must implement.
Definition Stream.hpp:456
A stream that provides read-only stream functionality.
Definition Stream.hpp:126
virtual bool isReadable() const noexcept
Checks if the stream is readable.
Definition Stream.hpp:130
size_t read(const StridedMemoryView< T > &memoryView)
Reads data from the stream into a strided memory view.
Definition Stream.hpp:160
virtual bool invalidate()
In the stream is buffered, invalidates any buffered read data from the stream.
Optional< String > readString()
Reads data from the buffer as a C++ String.
Definition Stream.hpp:174
size_t read(const MemoryView< T > &memoryView)
Reads data from the strea into a memory view.
Definition Stream.hpp:149
virtual size_t read(void *data, size_t n)
Reads data from the data stream to a buffer of raw memory data with length n.
Optional< T > read()
Reads a trivially copyable obhect from the stream.
Definition Stream.hpp:193
Definition Exception.hpp:110
A stream that provides write-only stream functionality.
Definition Stream.hpp:233
size_t writeString(const StringView string)
Writes a string to the data stream.
Definition Stream.hpp:286
size_t write(const MemoryView< const T > &memoryView)
Writes data from a memory view to the stream.
Definition Stream.hpp:259
virtual size_t write(const void *data, size_t n)
Writes data to the data stream from a buffer of raw memory data with length n.
virtual bool flush()
In the stream is buffered, invalidates any buffered write data from to stream.
virtual bool isWritable() const noexcept
Checks if the stream is writable.
Definition Stream.hpp:237
bool write(T value)
Writes a trivially copyable object to the stream.
Definition Stream.hpp:293
size_t write(const StridedMemoryView< const T > &memoryView)
Writes data from a strided memory view to the stream.
Definition Stream.hpp:270
An interface that all data streams must implement.
Definition Stream.hpp:58
IStream(const IStream &) noexcept=delete
virtual size_t tell()
Gets the absolute stream position, in bytes.
void skip(const size_t n)
Skips n bytes from the data stream.
Definition Stream.hpp:91
virtual size_t size()
Gets the number of bytes available on the stream.
IStream & operator=(const IStream &) noexcept=delete
Seek
An enumeration that describes how a data stream should be seeked.
Definition Stream.hpp:72
virtual bool isSeekable(Seek mode=Seek::Start) const noexcept
Checks if the stream is seekable.
Definition Stream.hpp:80
IStream(IStream &&) noexcept=default
virtual bool isTellable() const noexcept
Checks if the stream knows it's current absolute position.
Definition Stream.hpp:98
virtual void seek(std::streamsize position, Seek mode=Seek::Start)
Changes the position of the data stream.
virtual bool isSizeKnown() const noexcept
Checks if the stream knows the size of the data.
A streambuf implementation for a InputStream.
Definition Stream.hpp:809
size_t mBufferLength
The length of the allocated buffer.
Definition Stream.hpp:815
InputStreamBuffer(InputStream inputStream, size_t bufferLength=1024)
Creates a new StreamBuffer.
~InputStreamBuffer() final
Releases the ResourceStream.
InputStream mInputStream
The resource stream.
Definition Stream.hpp:812
A stream that provides read-only stream functionality.
Definition Stream.hpp:210
InputStream(InputStream &&) noexcept=default
A data stream that reads or writes data into a memory buffer.
Definition Stream.hpp:693
MemoryView< Byte > getData()
Gets a view to the underlying memory data.
Definition Stream.hpp:733
size_t size() final
Gets the number of bytes available on the stream.
Definition Stream.hpp:762
MemoryDataStream(const MemoryDataStream &)
MemoryDataStream()
Allocates a new empty memory data stream.
MemoryDataStream(const ByteMemoryView &buffer, bool freeOnClose=false)
Wrap an existing memory chunk in a stream.
MemoryDataStream(MemoryDataStream &&) noexcept
MemoryDataStream(Byte *memory, size_t size, bool freeOnClose=false)
Wrap an existing memory chunk in a stream.
bool isTellable() const noexcept final
Checks if the stream knows it's current absolute position.
Definition Stream.hpp:753
bool growIfNeeded(std::size_t desiredSize)
Grows the memory stream if needed.
MemoryDataStream(DataStream &stream)
Copies all contents of the existing data stream into a memory stream.
size_t tell() final
Gets the absolute stream position, in bytes.
Definition Stream.hpp:756
bool isReadable() const noexcept final
Checks if the stream is readable.
Definition Stream.hpp:765
ByteMemoryView mBuffer
Definition Stream.hpp:694
MemoryDataStream(size_t size)
Allocates a new chunk of memory and wraps it in a stream.
bool isSeekable(const Seek mode=Seek::Start) const noexcept final
Checks if the stream is seekable.
Definition Stream.hpp:740
size_t write(const void *data, size_t n) final
Writes data to the data stream from a buffer of raw memory data with length n.
bool isSizeKnown() const noexcept final
Checks if the stream knows the size of the data.
Definition Stream.hpp:759
void seek(std::streamsize position, Seek mode=Seek::Start) final
Changes the position of the data stream.
bool isGrowable() const
Determines if write or seek calls can grow the underlying memory buffer.
Definition Stream.hpp:736
bool isWritable() const noexcept final
Checks if the stream is writable.
Definition Stream.hpp:772
size_t read(void *data, size_t n) final
Reads data from the data stream to a buffer of raw memory data with length n.
A memory view is a class which attaches to an chunk of memory and provides a view to it (optionally c...
Definition MemoryView.hpp:62
SizeType size() const noexcept
Gets the size of the view as number of elements.
Definition MemoryView.hpp:294
MemoryView< T > slice(SizeType offset, SizeType length=~0ul) const noexcept
Slices the memory view by taking the element that starts at offset and returns a new view with the gi...
Definition MemoryView.hpp:145
ConstPointer data() const noexcept
Gets a pointer to the first element in the view.
Definition MemoryView.hpp:227
Definition Optional.hpp:17
A stream that provides write-only stream functionality.
Definition Stream.hpp:307
OutputStream(const ByteMemoryView &buffer, bool freeOnClose=false)
Wrap an existing memory chunk in a stream.
OutputStream(const FilePath &path)
Creates a new file stream by opening the file at the given path.
A pointer type that has value semantics.
Definition Poly.hpp:57
friend class Poly
Definition Poly.hpp:58
Definition Stream.hpp:34
An interface that all data streams must implement.
Definition Stream.hpp:116
Definition Stream.hpp:35
Definition Stream.hpp:36
A memory view is a class which attaches to an chunk of memory and provides a view to it (optionally c...
Definition MemoryView.hpp:439
An adapter stream that turns an DataStream into an AsyncDataStream.
Definition Stream.hpp:566
bool isSeekable(const Seek mode=Seek::Start) const noexcept final
Checks if the stream is seekable.
Definition Stream.hpp:576
DataStream mDataStream
Definition Stream.hpp:568
bool isTellable() const noexcept final
Checks if the stream knows the size of the data.
Definition Stream.hpp:585
SyncDataStreamAdapter(DataStream dataStream, ExecutionContext &executionContext)
ExecutionContext & mExecutionContext
Definition Stream.hpp:569
Async wait() final
Waits until all pending operations on the stream are complete.
Async< size_t > size() final
Gets the number of bytes available on the stream.
Async< size_t > tell() final
Gets the number of bytes available on the stream.
bool isWritable() const noexcept final
Checks if the stream is writable.
Definition Stream.hpp:614
Async seek(std::streamsize position, Seek mode=Seek::Start) final
Changes the position of the data stream.
Async< size_t > read(void *data, size_t n) final
Reads data from the data stream to a buffer of raw memory data with length n.
Async< size_t > write(const void *data, size_t n) final
Writes data tp the data stream from a buffer of raw memory data with length n.
Definition Application.hpp:19
Byte
Definition DataTypes.hpp:40
Async asyncBinaryWrite(AsyncOutputStream &stream, const T &value, Args &&... args)
Definition Stream.hpp:874
constexpr std::size_t kStreamPolySize
The size used by Stream and other polymorphic types for small object optimization.
Definition Stream.hpp:42
cti::continuable< Args... > Async
Defines a non-copyable continuation type which uses the function2 backend for type erasure.
Definition Async.hpp:22
auto move(Vector3 position)
Moves a entity to the given position.
Definition Helpers.hpp:22
Async< T > asyncBinaryRead(AsyncInputStream &stream, Args &&... args)
Definition Stream.hpp:852
void binaryWrite(OutputStream &stream, const T &value, Args &&... args)
Writes a binary representation of T to the stream.
Definition Stream.hpp:864
std::uint32_t UInt32
Definition DataTypes.hpp:23
constexpr size_t hash(const T &v)
Generates a hash for the provided type.
Definition Hash.hpp:25
T binaryRead(InputStream &stream, Args &&... args)
Reads a binary representation of T from the stream.
Definition Stream.hpp:842
Definition Span.hpp:668
static Async< Type > asyncRead(S &stream, Args &&... args)
Definition Stream.hpp:936
static Async asyncWrite(S &stream, const Type &value)
Definition Stream.hpp:958
static void write(S &stream, const Type &value)
Definition Stream.hpp:949
static Type read(S &stream, Args &&... args)
Definition Stream.hpp:923
static void write(IOutputStream &stream, const Type &value)
Definition Stream.hpp:973
static T read(S &stream)
Definition Stream.hpp:886
static void write(S &stream, const T &value)
Definition Stream.hpp:904
static Async asyncWrite(S &stream, T value)
Definition Stream.hpp:911
static Async< T > asyncRead(S &stream)
Definition Stream.hpp:895
A class that can be specialized to implement support for custom binary serialization of a type.
Definition Stream.hpp:837