5#include "Stroika/Foundation/Streams/InternallySynchronizedInputOutputStream.h"
7namespace Stroika::Foundation::Streams::LoggingInputOutputStream {
11 template <
typename ELEMENT_TYPE>
12 class Rep_ final :
public InputOutputStream::IRep<ELEMENT_TYPE> {
14 Rep_ (
const typename InputOutputStream::Ptr<ELEMENT_TYPE>& realStream,
const typename OutputStream::Ptr<ELEMENT_TYPE>& logInput,
15 const typename OutputStream::Ptr<ELEMENT_TYPE>& logOutput)
16 : fRealStream_{realStream}
17 , fLogInput_{logInput}
18 , fLogOutput_{logOutput}
20 Require (not realStream.IsSeekable () or (logInput.IsSeekable () and logOutput.IsSeekable ()));
25 virtual bool IsSeekable ()
const override
27 return fRealStream_.IsSeekable ();
32 virtual void CloseRead ()
override
35 fRealStream_.CloseRead ();
38 Ensure (not IsOpenRead ());
40 virtual bool IsOpenRead ()
const override
42 return fRealStream_.IsOpenRead ();
46 return fRealStream_.GetReadOffset ();
48 virtual SeekOffsetType SeekRead (Whence whence, SignedSeekOffsetType offset)
override
55 virtual optional<size_t> AvailableToRead ()
override
57 return fRealStream_.AvailableToRead ();
59 virtual optional<span<ELEMENT_TYPE>> Read (span<ELEMENT_TYPE> intoBuffer, NoDataAvailableHandling blockFlag)
override
61 optional<span<ELEMENT_TYPE>> result = fRealStream_.Read (intoBuffer, blockFlag);
63 fLogInput_.Write (*result);
70 virtual void CloseWrite ()
override
74 fRealStream_.CloseWrite ();
76 Assert (fRealStream_ ==
nullptr);
77 Ensure (not IsOpenWrite ());
79 virtual bool IsOpenWrite ()
const override
82 return fRealStream_.IsOpenWrite ();
87 return fRealStream_.GetWriteOffset ();
89 virtual SeekOffsetType SeekWrite (Whence whence, SignedSeekOffsetType offset)
override
91 Require (IsOpenWrite ());
94 [[maybe_unused]]
SeekOffsetType o2 = fLogOutput_.Seek (whence, offset);
97 virtual void Flush ()
override
100 Require (IsOpenWrite ());
101 fRealStream_.Flush ();
105 virtual void Write (span<const ELEMENT_TYPE> elts)
override
107 Require (not elts.empty ());
108 Require (IsOpenWrite ());
110 fRealStream_.Write (elts);
111 fLogOutput_.Write (elts);
115 typename InputOutputStream::Ptr<ELEMENT_TYPE> fRealStream_;
116 typename OutputStream::Ptr<ELEMENT_TYPE> fLogInput_;
117 typename OutputStream::Ptr<ELEMENT_TYPE> fLogOutput_;
118 [[no_unique_address]] Debug::AssertExternallySynchronizedMutex fThisAssertExternallySynchronized_;
127 template <
typename ELEMENT_TYPE>
131 return _mkPtr (Memory::MakeSharedPtr<Private_::Rep_> (realStream, logInput, logOutput));
133 template <
typename ELEMENT_TYPE>
137 switch (internallySynchronized) {
138 case Execution::eInternallySynchronized:
139 return InternallySynchronizedInputOutputStream::New<Private_::Rep_> ({}, realStream, logInput, logOutput);
140 case Execution::eNotKnownInternallySynchronized:
141 return New<ELEMENT_TYPE> (realStream, logInput, logOutput);
#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...
OutputStream<>::Ptr is Smart pointer to a stream-based sink of data.
A Streams::Ptr<ELEMENT_TYPE> is a smart-pointer to a stream of elements of type T.