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