Stroika Library 3.0d23x
 
Loading...
Searching...
No Matches
SplitterOutputStream.inl
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2026. All rights reserved
3 */
6#include "Stroika/Foundation/Streams/InternallySynchronizedOutputStream.h"
7
8namespace Stroika::Foundation::Streams::SplitterOutputStream {
9
10 namespace Private_ {
11 template <typename ELEMENT_TYPE>
12 class Rep_ : public OutputStream::IRep<ELEMENT_TYPE> {
13 public:
14 Rep_ (const typename OutputStream::Ptr<ELEMENT_TYPE>& realOut1, const typename OutputStream::Ptr<ELEMENT_TYPE>& realOut2)
15 : fRealOut1_{realOut1}
16 , fRealOut2_{realOut2}
17 {
18 }
19
20 public:
21 virtual bool IsSeekable () const override
22 {
23 Debug::AssertExternallySynchronizedMutex::ReadContext declareContext{fThisAssertExternallySynchronized_};
24 return fRealOut1_.IsSeekable () and fRealOut2_.IsSeekable ();
25 }
26 virtual void CloseWrite () override
27 {
28 Debug::AssertExternallySynchronizedMutex::WriteContext declareContext{fThisAssertExternallySynchronized_};
29 if (IsOpenWrite ()) {
30 fRealOut1_.CloseWrite ();
31 fRealOut2_.CloseWrite ();
32 }
33 Assert (fRealOut1_ == nullptr);
34 Assert (fRealOut2_ == nullptr);
35 Ensure (not IsOpenWrite ());
36 }
37 virtual bool IsOpenWrite () const override
38 {
39 Debug::AssertExternallySynchronizedMutex::ReadContext declareContext{fThisAssertExternallySynchronized_};
40 Assert (fRealOut1_.IsOpenWrite () == fRealOut2_.IsOpenWrite ());
41 return fRealOut1_.IsOpenWrite ();
42 }
43 virtual SeekOffsetType GetWriteOffset () const override
44 {
45 Debug::AssertExternallySynchronizedMutex::ReadContext declareContext{fThisAssertExternallySynchronized_};
46 Assert (fRealOut1_.GetWriteOffset () == fRealOut2_.GetWriteOffset ());
47 return fRealOut1_.GetWriteOffset ();
48 }
49 virtual SeekOffsetType SeekWrite (Whence whence, SignedSeekOffsetType offset) override
50 {
51 Require (IsOpenWrite ());
52 Debug::AssertExternallySynchronizedMutex::WriteContext declareContext{fThisAssertExternallySynchronized_};
53 SeekOffsetType o1 = fRealOut1_.SeekWrite (whence, offset);
54 [[maybe_unused]] SeekOffsetType o2 = fRealOut2_.SeekWrite (whence, offset);
55 Assert (o1 == o2);
56 return o1;
57 }
58 virtual void Flush () override
59 {
60 Debug::AssertExternallySynchronizedMutex::WriteContext declareContext{fThisAssertExternallySynchronized_};
61 Require (IsOpenWrite ());
62 fRealOut1_.Flush ();
63 fRealOut2_.Flush ();
64 }
65 // pointer must refer to valid memory at least bufSize long, and cannot be nullptr. BufSize must always be >= 1.
66 // Writes always succeed fully or throw.
67 virtual void Write (span<const ELEMENT_TYPE> elts) override
68 {
69 Require (start < end); // for OutputStream<byte> - this function requires non-empty write
70 Require (IsOpenWrite ());
71 Debug::AssertExternallySynchronizedMutex::WriteContext declareContext{fThisAssertExternallySynchronized_};
72 fRealOut1_.Write (start, end);
73 fRealOut2_.Write (start, end);
74 }
75
76 private:
77 typename OutputStream::Ptr<ELEMENT_TYPE> fRealOut1_;
78 typename OutputStream::Ptr<ELEMENT_TYPE> fRealOut2_;
79 [[no_unique_address]] Debug::AssertExternallySynchronizedMutex fThisAssertExternallySynchronized_;
80 };
81 }
82
83 /*
84 ********************************************************************************
85 ********************** Streams::SplitterOutputStream::New **********************
86 ********************************************************************************
87 */
88 template <typename ELEMENT_TYPE>
89 inline auto New (const typename OutputStream::Ptr<ELEMENT_TYPE>& realOut1, const typename OutputStream::Ptr<ELEMENT_TYPE>& realOut2)
91 {
92 return Memory::MakeSharedPtr<Private_::Rep_> (realOut1, realOut2);
93 }
94 template <typename ELEMENT_TYPE>
95 inline auto New (Execution::InternallySynchronized internallySynchronized, const typename OutputStream::Ptr<ELEMENT_TYPE>& realOut1,
96 const typename OutputStream::Ptr<ELEMENT_TYPE>& realOut2) -> Ptr<ELEMENT_TYPE>
97 {
98 switch (internallySynchronized) {
99 case Execution::eInternallySynchronized:
100 return Streams::InternallySynchronizedOutputStream::New<Private_::Rep_> ({}, fileName, seekable);
101 case Execution::eNotKnownInternallySynchronized:
102 return New<ELEMENT_TYPE> (realOut1, realOut2);
103 default:
105 return nullptr;
106 }
107 }
108
109}
#define RequireNotReached()
Definition Assertions.h:385
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.
Definition Stream.h:170