6#include "Stroika/Foundation/Execution/Exceptions.h"
7#include "Stroika/Foundation/Execution/Throw.h"
9namespace Stroika::Foundation::Streams::iostream::InputStreamFromStdIStream {
12 template <
typename ELEMENT_TYPE,
typename BASIC_ISTREAM_ELEMENT_TYPE,
typename BASIC_ISTREAM_TRAITS_TYPE>
13 class Rep_ :
public InputStream::IRep<ELEMENT_TYPE> {
18 Rep_ (basic_istream<BASIC_ISTREAM_ELEMENT_TYPE, BASIC_ISTREAM_TRAITS_TYPE>& originalStream)
19 : Rep_{originalStream, eSeekable}
22 Rep_ (basic_istream<BASIC_ISTREAM_ELEMENT_TYPE, BASIC_ISTREAM_TRAITS_TYPE>& originalStream, SeekableFlag seekable)
23 : fOriginalStreamRef_{originalStream}
24 , fSeekable_{seekable}
29 virtual bool IsSeekable ()
const override
31 return fSeekable_ == eSeekable;
33 virtual void CloseRead ()
override
36 Ensure (not IsOpenRead ());
38 virtual bool IsOpenRead ()
const override
42 virtual optional<size_t> AvailableToRead ()
override
45 streamsize sz = fOriginalStreamRef_.rdbuf ()->in_avail ();
53 return static_cast<size_t> (sz);
55 virtual optional<SeekOffsetType> RemainingLength ()
override
58 Require (IsOpenRead ());
62 virtual optional<span<ELEMENT_TYPE>> Read (span<ELEMENT_TYPE> intoBuffer, NoDataAvailableHandling blockFlag)
override
64 Require (not intoBuffer.empty ());
66 Require (IsOpenRead ());
67 if (fOriginalStreamRef_.eof ()) {
68 return span<ELEMENT_TYPE>{};
70 if (blockFlag == NoDataAvailableHandling::eDontBlock and AvailableToRead () == nullopt) {
73 size_t maxToRead = intoBuffer.size ();
74 fOriginalStreamRef_.clear ();
75 fOriginalStreamRef_.read (
reinterpret_cast<BASIC_ISTREAM_ELEMENT_TYPE*
> (intoBuffer.data ()), maxToRead);
76 size_t n =
static_cast<size_t> (fOriginalStreamRef_.gcount ());
77 Assert (n <= maxToRead);
79 if (not fOriginalStreamRef_.eof () and fOriginalStreamRef_.fail ()) [[unlikely]] {
80 static const Execution::RuntimeErrorException kException_{
"Failed to read from istream"sv};
83 return intoBuffer.subspan (0, n);
89 Require (IsOpenRead ());
90 return fOriginalStreamRef_.rdbuf ()->pubseekoff (0, ios_base::cur, ios_base::in);
92 virtual SeekOffsetType SeekRead (Whence whence, SignedSeekOffsetType offset)
override
95 Require (IsOpenRead ());
96 fOriginalStreamRef_.clear ();
99 fOriginalStreamRef_.seekg (offset, ios::beg);
102 fOriginalStreamRef_.seekg (offset, ios::cur);
105 fOriginalStreamRef_.seekg (offset, ios::end);
109 return fOriginalStreamRef_.rdbuf ()->pubseekoff (0, ios_base::cur, ios_base::in);
113 basic_istream<BASIC_ISTREAM_ELEMENT_TYPE, BASIC_ISTREAM_TRAITS_TYPE>& fOriginalStreamRef_;
115 [[no_unique_address]] Debug::AssertExternallySynchronizedMutex fThisAssertExternallySynchronized_;
124 template <
typename ELEMENT_TYPE,
typename BASIC_ISTREAM_ELEMENT_TYPE,
typename BASIC_ISTREAM_TRAITS_TYPE>
125 inline auto New (basic_istream<BASIC_ISTREAM_ELEMENT_TYPE, BASIC_ISTREAM_TRAITS_TYPE>& originalStream) ->
Ptr<ELEMENT_TYPE>
126 requires ((same_as<ELEMENT_TYPE, byte> and same_as<BASIC_ISTREAM_ELEMENT_TYPE, char>) or
127 (same_as<ELEMENT_TYPE, Characters::Character> and same_as<BASIC_ISTREAM_ELEMENT_TYPE, wchar_t>))
129 return Ptr<ELEMENT_TYPE>{make_shared<Private_::Rep_<ELEMENT_TYPE, BASIC_ISTREAM_ELEMENT_TYPE, BASIC_ISTREAM_TRAITS_TYPE>> (originalStream)};
131 template <
typename ELEMENT_TYPE,
typename BASIC_ISTREAM_ELEMENT_TYPE,
typename BASIC_ISTREAM_TRAITS_TYPE>
132 inline auto New (basic_istream<BASIC_ISTREAM_ELEMENT_TYPE, BASIC_ISTREAM_TRAITS_TYPE>& originalStream,
SeekableFlag seekable) ->
Ptr<ELEMENT_TYPE>
133 requires ((same_as<ELEMENT_TYPE, byte> and same_as<BASIC_ISTREAM_ELEMENT_TYPE, char>) or
134 (same_as<ELEMENT_TYPE, Characters::Character> and same_as<BASIC_ISTREAM_ELEMENT_TYPE, wchar_t>))
137 make_shared<Private_::Rep_<ELEMENT_TYPE, BASIC_ISTREAM_ELEMENT_TYPE, BASIC_ISTREAM_TRAITS_TYPE>> (originalStream, seekable)};
139 template <
typename ELEMENT_TYPE,
typename BASIC_ISTREAM_ELEMENT_TYPE,
typename BASIC_ISTREAM_TRAITS_TYPE>
141 basic_istream<BASIC_ISTREAM_ELEMENT_TYPE, BASIC_ISTREAM_TRAITS_TYPE>& originalStream) -> Ptr<ELEMENT_TYPE>
142 requires ((same_as<ELEMENT_TYPE, byte> and same_as<BASIC_ISTREAM_ELEMENT_TYPE, char>) or
143 (same_as<ELEMENT_TYPE, Characters::Character> and same_as<BASIC_ISTREAM_ELEMENT_TYPE, wchar_t>))
145 switch (internallySynchronized) {
146 case Execution::eInternallySynchronized:
147 return InternallySynchronizedInputStream::New<Private_::Rep_<ELEMENT_TYPE, BASIC_ISTREAM_ELEMENT_TYPE, BASIC_ISTREAM_TRAITS_TYPE>> (
149 case Execution::eNotKnownInternallySynchronized:
150 return New<ELEMENT_TYPE> (originalStream);
156 template <
typename ELEMENT_TYPE,
typename BASIC_ISTREAM_ELEMENT_TYPE,
typename BASIC_ISTREAM_TRAITS_TYPE>
158 basic_istream<BASIC_ISTREAM_ELEMENT_TYPE, BASIC_ISTREAM_TRAITS_TYPE>& originalStream, SeekableFlag seekable) -> Ptr<ELEMENT_TYPE>
159 requires ((same_as<ELEMENT_TYPE, byte> and same_as<BASIC_ISTREAM_ELEMENT_TYPE, char>) or
160 (same_as<ELEMENT_TYPE, Characters::Character> and same_as<BASIC_ISTREAM_ELEMENT_TYPE, wchar_t>))
162 switch (internallySynchronized) {
163 case Execution::eInternallySynchronized:
164 return InternallySynchronizedInputStream::New<Private_::Rep_<ELEMENT_TYPE, BASIC_ISTREAM_ELEMENT_TYPE, BASIC_ISTREAM_TRAITS_TYPE>> (
166 case Execution::eNotKnownInternallySynchronized:
167 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...