Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
InternallySynchronizedInputOutputStream.inl
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
5
6namespace Stroika::Foundation::Streams::InternallySynchronizedInputOutputStream {
7
8 namespace Private_ {
9 template <typename BASE_REP_TYPE, typename OPTIONS>
10 struct Rep_ final : Memory::InheritAndUseBlockAllocationIfAppropriate<Rep_<BASE_REP_TYPE, OPTIONS>, BASE_REP_TYPE> {
11 using inherited = Memory::InheritAndUseBlockAllocationIfAppropriate<Rep_<BASE_REP_TYPE, OPTIONS>, BASE_REP_TYPE>;
12 using ElementType = typename BASE_REP_TYPE::ElementType;
13 template <typename... ARGS>
14 Rep_ (OPTIONS o, ARGS&&... args)
15 : inherited{forward<ARGS> (args)...}
16 , fOptions_{o}
17 {
18 }
19 Rep_ (const Rep_&) = delete;
20 virtual bool IsSeekable () const override
21 {
22 [[maybe_unused]] lock_guard critSec{fCriticalSection_};
23 return BASE_REP_TYPE::IsSeekable ();
24 }
25 virtual void CloseRead () override
26 {
27 [[maybe_unused]] lock_guard critSec{fCriticalSection_};
28 BASE_REP_TYPE::CloseRead ();
29 }
30 virtual bool IsOpenRead () const override
31 {
32 [[maybe_unused]] lock_guard critSec{fCriticalSection_};
33 return BASE_REP_TYPE::IsOpenRead ();
34 }
35 virtual SeekOffsetType GetReadOffset () const override
36 {
37 [[maybe_unused]] lock_guard critSec{fCriticalSection_};
38 Require (IsOpenRead ());
39 return BASE_REP_TYPE::GetReadOffset ();
40 }
41 virtual SeekOffsetType SeekRead (Whence whence, SignedSeekOffsetType offset) override
42 {
43 [[maybe_unused]] lock_guard critSec{fCriticalSection_};
44 Require (IsOpenRead ());
45 return BASE_REP_TYPE::SeekRead (whence, offset);
46 }
47 virtual optional<size_t> AvailableToRead () override
48 {
49 [[maybe_unused]] lock_guard critSec{fCriticalSection_};
50 Require (IsOpenRead ());
51 return BASE_REP_TYPE::AvailableToRead ();
52 }
53 virtual optional<SeekOffsetType> RemainingLength () override
54 {
55 [[maybe_unused]] lock_guard critSec{fCriticalSection_};
56 Require (IsOpenRead ());
57 return BASE_REP_TYPE::RemainingLength ();
58 }
59 virtual optional<span<ElementType>> Read (span<ElementType> intoBuffer, NoDataAvailableHandling blockFlag) override
60 {
61 [[maybe_unused]] lock_guard critSec{fCriticalSection_};
62 Require (IsOpenRead ());
63 return BASE_REP_TYPE::Read (intoBuffer, blockFlag);
64 }
65 virtual void CloseWrite () override
66 {
67 [[maybe_unused]] lock_guard critSec{fCriticalSection_};
68 BASE_REP_TYPE::CloseWrite ();
69 }
70 virtual bool IsOpenWrite () const override
71 {
72 [[maybe_unused]] lock_guard critSec{fCriticalSection_};
73 return BASE_REP_TYPE::IsOpenWrite ();
74 }
75 virtual SeekOffsetType GetWriteOffset () const override
76 {
77 [[maybe_unused]] lock_guard critSec{fCriticalSection_};
78 Require (IsOpenWrite ());
79 return BASE_REP_TYPE::GetWriteOffset ();
80 }
81 virtual SeekOffsetType SeekWrite (Whence whence, SignedSeekOffsetType offset) override
82 {
83 [[maybe_unused]] lock_guard critSec{fCriticalSection_};
84 Require (IsOpenWrite ());
85 return BASE_REP_TYPE::SeekWrite (whence, offset);
86 }
87 virtual void Write (span<const ElementType> elts) override
88 {
89 [[maybe_unused]] lock_guard critSec{fCriticalSection_};
90 Require (IsOpenWrite ());
91 BASE_REP_TYPE::Write (elts);
92 }
93 virtual void Flush () override
94 {
95 [[maybe_unused]] lock_guard critSec{fCriticalSection_};
96 Require (IsOpenWrite ());
97 BASE_REP_TYPE::Flush ();
98 }
99
100 private:
101 [[no_unique_address]] OPTIONS fOptions_;
102 mutable typename OPTIONS::MutexType fCriticalSection_;
103 };
104 template <typename ELEMENT_TYPE, typename OPTIONS>
105 struct Rep2_ : InputOutputStream::IRep<ELEMENT_TYPE> {
106 using ElementType = ELEMENT_TYPE;
107 Rep2_ ([[maybe_unused]] const OPTIONS& o, const InputOutputStream::Ptr<ELEMENT_TYPE>& stream2Wrap)
108 : fStream2Wrap{stream2Wrap}
109 {
110 }
111 virtual bool IsSeekable () const override
112 {
113 [[maybe_unused]] lock_guard critSec{fCriticalSection_};
114 return fStream2Wrap.IsSeekable ();
115 }
116 virtual void CloseRead () override
117 {
118 [[maybe_unused]] lock_guard critSec{fCriticalSection_};
119 if (IsOpenRead ()) {
120 fStream2Wrap.CloseRead ();
121 }
122 Ensure (not IsOpenRead ());
123 }
124 virtual bool IsOpenRead () const override
125 {
126 [[maybe_unused]] lock_guard critSec{fCriticalSection_};
127 return fStream2Wrap.IsOpenRead ();
128 }
129 virtual SeekOffsetType GetReadOffset () const override
130 {
131 [[maybe_unused]] lock_guard critSec{fCriticalSection_};
132 Require (IsOpenRead ());
133 return fStream2Wrap.GetReadOffset ();
134 }
135 virtual SeekOffsetType SeekRead (Whence whence, SignedSeekOffsetType offset) override
136 {
137 [[maybe_unused]] lock_guard critSec{fCriticalSection_};
138 Require (IsOpenRead ());
139 return fStream2Wrap.SeekRead (whence, offset);
140 }
141 virtual optional<size_t> AvailableToRead () override
142 {
143 [[maybe_unused]] lock_guard critSec{fCriticalSection_};
144 Require (IsOpenRead ());
145 return fStream2Wrap.AvailableToRead ();
146 }
147 virtual optional<SeekOffsetType> RemainingLength () override
148 {
149 [[maybe_unused]] lock_guard critSec{fCriticalSection_};
150 Require (IsOpenRead ());
151 return fStream2Wrap.RemainingLength ();
152 }
153 virtual size_t Read (span<ElementType> intoBuffer, NoDataAvailableHandling blockFlag) override
154 {
155 [[maybe_unused]] lock_guard critSec{fCriticalSection_};
156 Require (IsOpenRead ());
157 return fStream2Wrap.Read (intoBuffer, blockFlag);
158 }
159
160 private:
161 InputOutputStream::Ptr<ELEMENT_TYPE> fStream2Wrap;
162 mutable typename OPTIONS::MutexType fCriticalSection_;
163 };
164 }
165
166 /*
167 ********************************************************************************
168 ******** InternallySynchronizedInputOutputStream<BASE_REP_TYPE>::New ***********
169 ********************************************************************************
170 */
171 template <typename BASE_REP_TYPE, typename OPTIONS, typename... ARGS>
172 inline auto New (const OPTIONS& o, ARGS&&... args) -> Ptr<typename BASE_REP_TYPE::ElementType>
173 {
174 return Ptr<typename BASE_REP_TYPE::ElementType>{make_shared<Private_::Rep_<BASE_REP_TYPE, OPTIONS>> (o, forward<ARGS> (args)...)};
175 }
176 template <typename ELEMENT_TYPE, typename OPTIONS>
177 inline Ptr<ELEMENT_TYPE> New (const OPTIONS& o, const InputOutputStream::Ptr<ELEMENT_TYPE>& stream2Wrap)
178 {
179 return Ptr<ELEMENT_TYPE>{make_shared<Private_::Rep2_<ELEMENT_TYPE, OPTIONS>> (o, stream2Wrap)};
180 }
181
182}