Stroika Library 3.0d18
 
Loading...
Searching...
No Matches
OutputStream.inl
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
5#include "Stroika/Foundation/Characters/LineEndings.h"
10
11namespace Stroika::Foundation::Streams::OutputStream {
12
13 /*
14 ********************************************************************************
15 ************************ OutputStream::Ptr<ELEMENT_TYPE> ***********************
16 ********************************************************************************
17 */
18 template <typename ELEMENT_TYPE>
19 inline Ptr<ELEMENT_TYPE>::Ptr (const shared_ptr<IRep<ELEMENT_TYPE>>& rep)
20 : inherited{rep}
21 {
22 }
23 template <typename ELEMENT_TYPE>
24 inline Ptr<ELEMENT_TYPE>::Ptr (nullptr_t)
25 : inherited{nullptr}
26 {
27 }
28 template <typename ELEMENT_TYPE>
29 inline auto Ptr<ELEMENT_TYPE>::GetSharedRep () const -> shared_ptr<IRep<ELEMENT_TYPE>>
30 {
31 return Debug::UncheckedDynamicPointerCast<IRep<ELEMENT_TYPE>> (inherited::GetSharedRep ());
32 }
33 template <typename ELEMENT_TYPE>
34 inline auto Ptr<ELEMENT_TYPE>::GetRepConstRef () const -> const IRep<ELEMENT_TYPE>&
35 {
36 return Debug::UncheckedDynamicCast<const IRep<ELEMENT_TYPE>&> (inherited::GetRepConstRef ());
37 }
38 template <typename ELEMENT_TYPE>
39 inline auto Ptr<ELEMENT_TYPE>::GetRepRWRef () const -> IRep<ELEMENT_TYPE>&
40 {
41 return Debug::UncheckedDynamicCast<IRep<ELEMENT_TYPE>&> (inherited::GetRepRWRef ());
42 }
43 template <typename ELEMENT_TYPE>
45 {
46 Debug::AssertExternallySynchronizedMutex::ReadContext declareContext{this->_fThisAssertExternallySynchronized};
47 Require (IsOpen ());
48 return GetRepConstRef ().GetWriteOffset ();
49 }
50 template <typename ELEMENT_TYPE>
52 {
53 Debug::AssertExternallySynchronizedMutex::ReadContext declareContext{this->_fThisAssertExternallySynchronized};
54 Require (IsOpen ());
55 Require (offset < static_cast<SeekOffsetType> (numeric_limits<SignedSeekOffsetType>::max ()));
56 return GetRepRWRef ().SeekWrite (Whence::eFromStart, static_cast<SignedSeekOffsetType> (offset));
57 }
58 template <typename ELEMENT_TYPE>
60 {
61 Debug::AssertExternallySynchronizedMutex::ReadContext declareContext{this->_fThisAssertExternallySynchronized};
62 Require (IsOpen ());
63 return GetRepRWRef ().SeekWrite (whence, offset);
64 }
65 template <typename ELEMENT_TYPE>
66 template <typename ELEMENT_TYPE2, size_t EXTENT_2>
67 inline void Ptr<ELEMENT_TYPE>::Write (span<ELEMENT_TYPE2, EXTENT_2> elts) const
68 requires (same_as<ELEMENT_TYPE, remove_cvref_t<ELEMENT_TYPE2>> or
69 (same_as<ELEMENT_TYPE, byte> and (same_as<remove_cvref_t<ELEMENT_TYPE2>, uint8_t>)) or
70 (same_as<ELEMENT_TYPE, Character> and (Characters::IUNICODECanUnambiguouslyConvertFrom<remove_cvref_t<ELEMENT_TYPE2>>)))
71 {
72 Debug::AssertExternallySynchronizedMutex::ReadContext declareContext{this->_fThisAssertExternallySynchronized};
73 Require (IsOpen ());
74 if (not elts.empty ()) [[likely]] {
75 if constexpr (same_as<ELEMENT_TYPE, byte>) {
76 GetRepRWRef ().Write (Memory::SpanBytesCast<span<const ELEMENT_TYPE>> (elts));
77 }
78 else if constexpr (same_as<ELEMENT_TYPE, Character>) {
79 if constexpr (sizeof (ELEMENT_TYPE2) == sizeof (Character)) {
80 GetRepRWRef ().Write (Memory::SpanBytesCast<span<const ELEMENT_TYPE>> (elts));
81 }
82 else {
83 Memory::StackBuffer<Character> buf{Memory::eUninitialized, Characters::UTFConvert::ComputeTargetBufferSize<Character> (elts)};
84 GetRepRWRef ().Write (Characters::UTFConvert::kThe.ConvertSpan (elts, span{buf}));
85 }
86 }
87 else {
88 GetRepRWRef ().Write (elts);
89 }
90 }
91 }
92 template <typename ELEMENT_TYPE>
93 inline void Ptr<ELEMENT_TYPE>::Write (const Memory::BLOB& blob) const
94 requires (same_as<ELEMENT_TYPE, byte>)
95 {
96 this->Write (blob.As<span<const byte>> ());
97 }
98 template <typename ELEMENT_TYPE>
99 inline void Ptr<ELEMENT_TYPE>::Write (const ELEMENT_TYPE& e) const
100 {
101 this->Write (span{&e, 1});
102 }
103 template <typename ELEMENT_TYPE>
104 void Ptr<ELEMENT_TYPE>::Write (const Characters::String& s) const
105 requires (same_as<ELEMENT_TYPE, Character>)
106 {
107 Memory::StackBuffer<Character> ignored;
108 this->Write (s.GetData<Character> (&ignored));
109 }
110 template <typename ELEMENT_TYPE>
111 template <Characters::IUNICODECanUnambiguouslyConvertFrom CHAR_T>
112 inline void Ptr<ELEMENT_TYPE>::Write (const CHAR_T* cStr) const
113 requires (same_as<ELEMENT_TYPE, Character>)
114 {
115 this->Write (span{cStr, Characters::CString::Length (cStr)});
116 }
117 template <typename ELEMENT_TYPE>
118 template <typename ELT_2_WRITE>
119 inline void Ptr<ELEMENT_TYPE>::WriteLn (ELT_2_WRITE&& arg) const
120 requires (same_as<ELEMENT_TYPE, Character>)
121 {
122 this->Write (forward<ELT_2_WRITE> (arg));
123 this->Write (Characters::kEOL<Character>);
124 }
125 template <typename ELEMENT_TYPE>
126 void Ptr<ELEMENT_TYPE>::PrintF (const wchar_t* format, ...)
127 requires (same_as<ELEMENT_TYPE, Character>)
128 {
129 RequireNotNull (format);
130 va_list argsList;
131 va_start (argsList, format);
132 Write (Characters::FormatV (format, argsList));
133 va_end (argsList);
134 }
135 template <typename ELEMENT_TYPE>
136 inline void Ptr<ELEMENT_TYPE>::Close () const
137 {
138 Debug::AssertExternallySynchronizedMutex::ReadContext declareContext{this->_fThisAssertExternallySynchronized};
139 GetRepRWRef ().CloseWrite ();
140 Ensure (not IsOpen ());
141 }
142 template <typename ELEMENT_TYPE>
143 inline void Ptr<ELEMENT_TYPE>::Close (bool reset)
144 {
145 Debug::AssertExternallySynchronizedMutex::WriteContext declareContext{this->_fThisAssertExternallySynchronized};
146 GetRepRWRef ().CloseWrite ();
147 if (reset) {
148 this->reset ();
149 }
150 Ensure (not IsOpen ());
151 }
152 template <typename ELEMENT_TYPE>
153 inline bool Ptr<ELEMENT_TYPE>::IsOpen () const
154 {
155 Debug::AssertExternallySynchronizedMutex::ReadContext declareContext{this->_fThisAssertExternallySynchronized};
156 return GetRepConstRef ().IsOpenWrite ();
157 }
158 template <typename ELEMENT_TYPE>
159 inline void Ptr<ELEMENT_TYPE>::Flush () const
160 {
161 Debug::AssertExternallySynchronizedMutex::ReadContext declareContext{this->_fThisAssertExternallySynchronized};
162 GetRepRWRef ().Flush ();
163 }
164 template <typename ELEMENT_TYPE>
165 template <typename T>
166 inline const typename OutputStream::Ptr<ELEMENT_TYPE>& Ptr<ELEMENT_TYPE>::operator<< (const T& write2TextStream) const
167 requires (same_as<ELEMENT_TYPE, Characters::Character>)
168 {
169 Debug::AssertExternallySynchronizedMutex::ReadContext declareContext{this->_fThisAssertExternallySynchronized};
170 Write (write2TextStream);
171 return *this;
172 }
173
174}
#define RequireNotNull(p)
Definition Assertions.h:347
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...
Abstract interface for output stream object. Don't call directly (use Ptr usually) - but use directly...
OutputStream<>::Ptr is Smart pointer to a stream-based sink of data.
nonvirtual void Flush() const
forces any data contained in this stream to be written.