4#include "InternallySynchronizedInputOutputStream.h"
6namespace Stroika::Foundation::Streams::LoggingInputOutputStream {
10 template <
typename ELEMENT_TYPE>
11 class Rep_ :
public InputOutputStream::IRep<ELEMENT_TYPE> {
13 Rep_ (
const typename InputOutputStream::Ptr<ELEMENT_TYPE>& realStream,
const typename OutputStream::Ptr<ELEMENT_TYPE>& logInput,
14 const typename OutputStream::Ptr<ELEMENT_TYPE>& logOutput)
15 : fRealStream_{realStream}
16 , fLogInput_{logInput}
17 , fLogOutput_{logOutput}
19 Require (not realStream.IsSeekable () or (logInput.IsSeekable () and logOutput.IsSeekable ()));
24 virtual bool IsSeekable ()
const override
26 return fRealStream_.IsSeekable ();
31 virtual void CloseRead ()
override
34 fRealStream_.CloseRead ();
37 Ensure (not IsOpenRead ());
39 virtual bool IsOpenRead ()
const override
41 return fRealStream_.IsOpenRead ();
45 return fRealStream_.GetReadOffset ();
47 virtual SeekOffsetType SeekRead (Whence whence, SignedSeekOffsetType offset)
override
54 virtual optional<size_t> AvailableToRead ()
override
56 return fRealStream_.AvailableToRead ();
58 virtual optional<span<ELEMENT_TYPE>> Read (span<ELEMENT_TYPE> intoBuffer, NoDataAvailableHandling blockFlag)
override
60 optional<span<ELEMENT_TYPE>> result = fRealStream_.Read (intoBuffer, blockFlag);
62 fLogInput_.Write (*result);
69 virtual void CloseWrite ()
override
73 fRealStream_.CloseWrite ();
75 Assert (fRealStream_ ==
nullptr);
76 Ensure (not IsOpenWrite ());
78 virtual bool IsOpenWrite ()
const override
81 return fRealStream_.IsOpenWrite ();
86 return fRealStream_.GetWriteOffset ();
88 virtual SeekOffsetType SeekWrite (Whence whence, SignedSeekOffsetType offset)
override
90 Require (IsOpenWrite ());
93 [[maybe_unused]]
SeekOffsetType o2 = fLogOutput_.Seek (whence, offset);
96 virtual void Flush ()
override
99 Require (IsOpenWrite ());
100 fRealStream_.Flush ();
104 virtual void Write (span<const ELEMENT_TYPE> elts)
override
106 Require (not elts.empty ());
107 Require (IsOpenWrite ());
109 fRealStream_.Write (elts);
110 fLogOutput_.Write (elts);
114 typename InputOutputStream::Ptr<ELEMENT_TYPE> fRealStream_;
115 typename OutputStream::Ptr<ELEMENT_TYPE> fLogInput_;
116 typename OutputStream::Ptr<ELEMENT_TYPE> fLogOutput_;
117 [[no_unique_address]] Debug::AssertExternallySynchronizedMutex fThisAssertExternallySynchronized_;
126 template <
typename ELEMENT_TYPE>
130 return _mkPtr (make_shared<Private_::Rep_> (realStream, logInput, logOutput));
132 template <
typename ELEMENT_TYPE>
136 switch (internallySynchronized) {
137 case Execution::eInternallySynchronized:
138 return InternallySynchronizedInputOutputStream::New<Private_::Rep_> ({}, realStream, logInput, logOutput);
139 case Execution::eNotKnownInternallySynchronized:
140 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.