6#include "Stroika/Foundation/Execution/Exceptions.h"
7#include "Stroika/Foundation/Execution/Throw.h"
10namespace Stroika::Foundation::Streams::iostream::InputStreamFromStdIStream {
13 template <
typename ELEMENT_TYPE,
typename BASIC_ISTREAM_ELEMENT_TYPE,
typename BASIC_ISTREAM_TRAITS_TYPE>
14 class Rep_ :
public InputStream::IRep<ELEMENT_TYPE> {
19 Rep_ (basic_istream<BASIC_ISTREAM_ELEMENT_TYPE, BASIC_ISTREAM_TRAITS_TYPE>& originalStream)
20 : Rep_{originalStream, eSeekable}
23 Rep_ (basic_istream<BASIC_ISTREAM_ELEMENT_TYPE, BASIC_ISTREAM_TRAITS_TYPE>& originalStream, SeekableFlag seekable)
24 : fOriginalStreamRef_{originalStream}
25 , fSeekable_{seekable}
30 virtual bool IsSeekable ()
const override
32 return fSeekable_ == eSeekable;
34 virtual void CloseRead ()
override
37 Ensure (not IsOpenRead ());
39 virtual bool IsOpenRead ()
const override
43 virtual optional<size_t> AvailableToRead ()
override
46 streamsize sz = fOriginalStreamRef_.rdbuf ()->in_avail ();
54 return static_cast<size_t> (sz);
56 virtual optional<SeekOffsetType> RemainingLength ()
override
59 Require (IsOpenRead ());
63 virtual optional<span<ELEMENT_TYPE>> Read (span<ELEMENT_TYPE> intoBuffer, NoDataAvailableHandling blockFlag)
override
65 Require (not intoBuffer.empty ());
67 Require (IsOpenRead ());
68 if (fOriginalStreamRef_.eof ()) {
69 return span<ELEMENT_TYPE>{};
71 if (blockFlag == NoDataAvailableHandling::eDontBlock and AvailableToRead () == nullopt) {
74 size_t maxToRead = intoBuffer.size ();
75 fOriginalStreamRef_.clear ();
76 fOriginalStreamRef_.read (
reinterpret_cast<BASIC_ISTREAM_ELEMENT_TYPE*
> (intoBuffer.data ()), maxToRead);
77 size_t n =
static_cast<size_t> (fOriginalStreamRef_.gcount ());
78 Assert (n <= maxToRead);
80 if (not fOriginalStreamRef_.eof () and fOriginalStreamRef_.fail ()) [[unlikely]] {
81 static const Execution::RuntimeErrorException kException_{
"Failed to read from istream"sv};
84 return intoBuffer.subspan (0, n);
90 Require (IsOpenRead ());
91 return fOriginalStreamRef_.rdbuf ()->pubseekoff (0, ios_base::cur, ios_base::in);
93 virtual SeekOffsetType SeekRead (Whence whence, SignedSeekOffsetType offset)
override
96 Require (IsOpenRead ());
97 fOriginalStreamRef_.clear ();
100 fOriginalStreamRef_.seekg (offset, ios::beg);
103 fOriginalStreamRef_.seekg (offset, ios::cur);
106 fOriginalStreamRef_.seekg (offset, ios::end);
110 return fOriginalStreamRef_.rdbuf ()->pubseekoff (0, ios_base::cur, ios_base::in);
114 basic_istream<BASIC_ISTREAM_ELEMENT_TYPE, BASIC_ISTREAM_TRAITS_TYPE>& fOriginalStreamRef_;
116 [[no_unique_address]] Debug::AssertExternallySynchronizedMutex fThisAssertExternallySynchronized_;
125 template <
typename ELEMENT_TYPE,
typename BASIC_ISTREAM_ELEMENT_TYPE,
typename BASIC_ISTREAM_TRAITS_TYPE>
126 inline auto New (basic_istream<BASIC_ISTREAM_ELEMENT_TYPE, BASIC_ISTREAM_TRAITS_TYPE>& originalStream) ->
Ptr<ELEMENT_TYPE>
127 requires ((same_as<ELEMENT_TYPE, byte> and same_as<BASIC_ISTREAM_ELEMENT_TYPE, char>) or
128 (same_as<ELEMENT_TYPE, Characters::Character> and same_as<BASIC_ISTREAM_ELEMENT_TYPE, wchar_t>))
130 return Ptr<ELEMENT_TYPE>{Memory::MakeSharedPtr<Private_::Rep_<ELEMENT_TYPE, BASIC_ISTREAM_ELEMENT_TYPE, BASIC_ISTREAM_TRAITS_TYPE>> (originalStream)};
132 template <
typename ELEMENT_TYPE,
typename BASIC_ISTREAM_ELEMENT_TYPE,
typename BASIC_ISTREAM_TRAITS_TYPE>
133 inline auto New (basic_istream<BASIC_ISTREAM_ELEMENT_TYPE, BASIC_ISTREAM_TRAITS_TYPE>& originalStream,
SeekableFlag seekable) ->
Ptr<ELEMENT_TYPE>
134 requires ((same_as<ELEMENT_TYPE, byte> and same_as<BASIC_ISTREAM_ELEMENT_TYPE, char>) or
135 (same_as<ELEMENT_TYPE, Characters::Character> and same_as<BASIC_ISTREAM_ELEMENT_TYPE, wchar_t>))
137 return Ptr<ELEMENT_TYPE>{Memory::MakeSharedPtr<Private_::Rep_<ELEMENT_TYPE, BASIC_ISTREAM_ELEMENT_TYPE, BASIC_ISTREAM_TRAITS_TYPE>> (
138 originalStream, seekable)};
140 template <
typename ELEMENT_TYPE,
typename BASIC_ISTREAM_ELEMENT_TYPE,
typename BASIC_ISTREAM_TRAITS_TYPE>
142 basic_istream<BASIC_ISTREAM_ELEMENT_TYPE, BASIC_ISTREAM_TRAITS_TYPE>& originalStream) -> Ptr<ELEMENT_TYPE>
143 requires ((same_as<ELEMENT_TYPE, byte> and same_as<BASIC_ISTREAM_ELEMENT_TYPE, char>) or
144 (same_as<ELEMENT_TYPE, Characters::Character> and same_as<BASIC_ISTREAM_ELEMENT_TYPE, wchar_t>))
146 switch (internallySynchronized) {
147 case Execution::eInternallySynchronized:
148 return InternallySynchronizedInputStream::New<Private_::Rep_<ELEMENT_TYPE, BASIC_ISTREAM_ELEMENT_TYPE, BASIC_ISTREAM_TRAITS_TYPE>> (
150 case Execution::eNotKnownInternallySynchronized:
151 return New<ELEMENT_TYPE> (originalStream);
157 template <
typename ELEMENT_TYPE,
typename BASIC_ISTREAM_ELEMENT_TYPE,
typename BASIC_ISTREAM_TRAITS_TYPE>
159 basic_istream<BASIC_ISTREAM_ELEMENT_TYPE, BASIC_ISTREAM_TRAITS_TYPE>& originalStream, SeekableFlag seekable) -> Ptr<ELEMENT_TYPE>
160 requires ((same_as<ELEMENT_TYPE, byte> and same_as<BASIC_ISTREAM_ELEMENT_TYPE, char>) or
161 (same_as<ELEMENT_TYPE, Characters::Character> and same_as<BASIC_ISTREAM_ELEMENT_TYPE, wchar_t>))
163 switch (internallySynchronized) {
164 case Execution::eInternallySynchronized:
165 return InternallySynchronizedInputStream::New<Private_::Rep_<ELEMENT_TYPE, BASIC_ISTREAM_ELEMENT_TYPE, BASIC_ISTREAM_TRAITS_TYPE>> (
167 case Execution::eNotKnownInternallySynchronized:
168 return New<ELEMENT_TYPE> (originalStream, seekable);
#define AssertNotImplemented()
#define RequireNotReached()
shared_lock< const AssertExternallySynchronizedMutex > ReadContext
Instantiate AssertExternallySynchronizedMutex::ReadContext to designate an area of code where protect...
unique_lock< AssertExternallySynchronizedMutex > WriteContext
Instantiate AssertExternallySynchronizedMutex::WriteContext to designate an area of code where protec...
A Streams::Ptr<ELEMENT_TYPE> is a smart-pointer to a stream of elements of type T.
void Throw(T &&e2Throw)
identical to builtin C++ 'throw' except that it does helpful, type dependent DbgTrace() messages firs...